package com.googlecode.kipler.satisfiability.completion.strategy;

import java.util.ArrayList;
import java.util.List;

import com.googlecode.kipler.container.dl.WorldConstraintSystem;
import com.googlecode.kipler.container.dl.operational.FilterType;
import com.googlecode.kipler.container.dl.operational.RelatedIndividualWithTypeFilter;
import com.googlecode.kipler.container.dl.operational.RelatedIndividualWithTypeFilterFactory;
import com.googlecode.kipler.satisfiability.blocking.abox.ABoxBlockingStrategy;
import com.googlecode.kipler.satisfiability.blocking.abox.OptimizedSHIQABoxBlocking;
import com.googlecode.kipler.satisfiability.completion.rule.individual.ABoxRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.AllValuesRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.AtLeastRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.AtMostRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.ChooseRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.IntersectionRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.LazyUnfoldingRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.PositiveConceptDefinitionRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.SHIQABoxBothRootMergeStrategy;
import com.googlecode.kipler.satisfiability.completion.rule.individual.SHIQABoxNotBothRootMergeStrategy;
import com.googlecode.kipler.satisfiability.completion.rule.individual.SomeValuesRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.TransitivityRule;
import com.googlecode.kipler.satisfiability.completion.rule.individual.UnionRule;
import com.googlecode.kipler.satisfiability.reasoner.Reasoner;
import com.googlecode.kipler.satisfiability.reasoner.ReasonerException;


/**
 * 
 * @author İnanç Seylan
 * 
 */
public class SHIQBasicCompletionStrategy implements CompletionStrategy {

	private PriorityBasedStrategy strategy;

	public SHIQBasicCompletionStrategy(Reasoner reasoner) {
		strategy = new PriorityBasedStrategy();
		setReasoner(reasoner);
		IndividualFeeder feeder = new BasicIndividualFeeder();
		ABoxBlockingStrategy blocking = new OptimizedSHIQABoxBlocking();
		RelatedIndividualWithTypeFilter filterer = RelatedIndividualWithTypeFilterFactory
				.getFilter(FilterType.TYPED_NEIGHBOR);
		List<ABoxRule> ruleList = new ArrayList<ABoxRule>();
		ruleList.add(new LazyUnfoldingRule());
		ruleList.add(new PositiveConceptDefinitionRule(blocking));
		ruleList.add(new IntersectionRule(blocking));
		ruleList.add(new AllValuesRule(blocking));
		ruleList.add(new TransitivityRule(blocking));
		ruleList.add(new UnionRule(getReasoner(), blocking));
		ruleList.add(new ChooseRule(getReasoner(), blocking));
		strategy.addIndividualRules(ruleList, false, feeder);

		ruleList = new ArrayList<ABoxRule>();
		ruleList.add(new AtMostRule(getReasoner(), blocking,
				new SHIQABoxBothRootMergeStrategy()));
		ruleList.add(new AtMostRule(getReasoner(), blocking,
				new SHIQABoxNotBothRootMergeStrategy()));
		strategy.addIndividualRules(ruleList, false, feeder);

		ruleList = new ArrayList<ABoxRule>();
		ruleList.add(new SomeValuesRule(blocking, filterer, false));
		ruleList.add(new AtLeastRule(blocking, filterer, false));
		strategy.addIndividualRules(ruleList, true, feeder);
	}

	@Override
	public void apply(WorldConstraintSystem currentWcs)
			throws ReasonerException {
		strategy.apply(currentWcs);
	}

	@Override
	public Reasoner getReasoner() {
		return strategy.getReasoner();
	}

	@Override
	public void setReasoner(Reasoner reasoner) {
		strategy.setReasoner(reasoner);
	}

}
